import org.jrtaudio.*;

public class OscillatorBank {

	final int TABLESIZE = 1000;
	final float C = (float)(TABLESIZE/(2*Math.PI));
	float sinebuffer[];
	
	float oscillators[];
	
	public OscillatorBank()
	{
		oscillators = new float[10];
		for(int i=0;i<oscillators.length;i++)
		{
			oscillators[i] = 0.05f + 0.05f*(float)Math.random();
		}
		
		sinebuffer = new float[TABLESIZE];
		float di = (float)(Math.PI*2/TABLESIZE);
		for(int i=0;i<TABLESIZE;i++)		
		{
			sinebuffer[i] = (float)Math.sin(di*i);
		}
	}
	
	public float fastersin(float t)
	{
		float ft = C * (t%((float)(2*Math.PI)));
		int fi = (int)Math.floor(ft);		
		return sinebuffer[fi];
	}
	
	public float mysin(float t)
	{
		float ft = C * (t%((float)(2*Math.PI)));
		int fi = (int)Math.floor(ft);
		float dt = ft - fi;
		return sinebuffer[fi]*dt + sinebuffer[(fi+1)%TABLESIZE]*(1-dt);
	}

	int counter = 0;
	public int callback(float[] outputBuffer, float[] inputBuffer, int nBufferFrames, double streamTime, int status)
	{
		for(int i=0;i<nBufferFrames;i++)
		{
			outputBuffer[i] = 0.f;
			for(float period: oscillators)
				outputBuffer[i] += mysin((i+counter)*period);
			outputBuffer[i] /= oscillators.length;
		}
		System.arraycopy(outputBuffer, 0, outputBuffer, nBufferFrames, nBufferFrames);
		
		counter += nBufferFrames;
		return 0;
	}	
	
	public static void main (String[] args) throws InterruptedException
	{
		JRtAudio audio = new JRtAudio();		
		audio.openStreamOut(new OscillatorBank());
		audio.startStream();
		Thread.sleep(10000);
		audio.closeStream();
	}
}
